package cn.wolfcode.shop.cloud.web.controller;

import cn.wolfcode.shop.cloud.common.*;
import cn.wolfcode.shop.cloud.domain.User;
import cn.wolfcode.shop.cloud.redis.key.SeckillRedisKey;
import cn.wolfcode.shop.cloud.redis.key.UserRedisKey;
import cn.wolfcode.shop.cloud.service.ISeckillGoodService;
import cn.wolfcode.shop.cloud.vo.SeckillGoodVo;
import cn.wolfcode.shop.cloud.web.msg.SeckillServerCodeMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.UUID;

/**
 * Created by wolfcode-lanxw
 */
@RestController
@RequestMapping("/api/path")
public class PathController {

    @Autowired
    private ISeckillGoodService seckillGoodService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/{seckillId}")
    public Result<String> getPath(@CookieValue(CookieUtils.USER_IN_TOKEN) String token,
            String verifyCode, @PathVariable("seckillId") Long seckillId) {
        User user = this.findUserByToken(token);
        // 验证码校验
        String verifyCodeInRedis = redisTemplate.opsForValue().get(SeckillRedisKey.SECKILL_VERIFY_CODE.join(seckillId + "", user.getId() + ""));
        if (!verifyCode.equals(verifyCodeInRedis)) {
            throw new BusinessException(SeckillServerCodeMsg.VERIFY_CODE_ERROR);
        }
        // 当验证通过以后,删除验证码
        redisTemplate.delete(SeckillRedisKey.SECKILL_VERIFY_CODE.join(seckillId + "", user.getId() + ""));
        SeckillGoodVo vo = seckillGoodService.findByCache(seckillId);
        // 1. 判断秒杀活动是否开启
        Date now = new Date();
        // 活动尚未开始: 如果当前时间小于结束时间成立, 就报错
        AssertUtil.isFalse(now.compareTo(vo.getStartDate()) < 0, SeckillServerCodeMsg.NOT_START_ERROR);
        // 活动已经结束: 如果当前时间 > 结束时间, 就报错
        AssertUtil.isFalse(now.compareTo(vo.getEndDate()) > 0, SeckillServerCodeMsg.SECKILL_OVER_ERROR);
        // 2. 生成 UUID 随机值
        String random = UUID.randomUUID().toString().replaceAll("-", "");
        // 3. 以秒杀id + 用户id 为key, 将 uuid 存储到 redis
        redisTemplate.opsForValue().set(
                SeckillRedisKey.SECKILL_RANDOM_PATH.join(seckillId + "", user.getId() + ""),
                random,
                SeckillRedisKey.SECKILL_RANDOM_PATH.getExpireTime(),
                SeckillRedisKey.SECKILL_RANDOM_PATH.getUnit());
        // 4. 将生成的uuid返回给前端
        return Result.success(random);
    }

    private User findUserByToken(String token) {
        String json = redisTemplate.opsForValue().get(UserRedisKey.USER_TOKEN.join(token));
        return JSONUtil.parseObject(json, User.class);
    }
}
